package jzqb.controller.admin;

import com.google.common.collect.Lists;
import haha.life.common.*;
import haha.life.normal.FileUtil;
import haha.life.normal.RandomUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jzqb.annotation.PermissionCheck.PermissionCheck;
import jzqb.bo.AdminDepartmentBo;
import jzqb.common.Result;
import jzqb.po.AdminDepartmentPo;
import jzqb.service.AdminDepartmentService;
import jzqb.service.MonitorService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.server.PathParam;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@RestController
@CrossOrigin
@RequestMapping("/adminDepartmentInfo")
@Api(tags = "部门后台接口")
public class AdminDepartmentInfoController {
    @Autowired
    private AdminDepartmentService admindepartmentservice;

    @Value("${filePath.updDptExcelPath}")
    private String updDptExcelPath;

    @Autowired
    private ExcelResolve excelResolve;

    @Autowired
    private MonitorService monitorService;

    @PermissionCheck(permissionTypeList  ={PermissionTypeTool.sys_mgt})
    @ApiOperation(value = "查询部门信息")
    @GetMapping("departmentlist")
    public Result layoutname(
            @PathParam("departmentcode") String departmentcode,
            @PathParam("departmentname") String departmentname,
            @PathParam("orderType") String orderType,
            @PathParam("orderValue") String orderValue,
            @PathParam("page") int page,
            @PathParam("pageSize") int pageSize
    ) {
        AdminDepartmentBo adminDepartmentBo = new AdminDepartmentBo();
        adminDepartmentBo.setDepartmentCode(departmentcode);
        adminDepartmentBo.setDepartmentName(departmentname);
        adminDepartmentBo.setOrderType(orderType);
        adminDepartmentBo.setOrderValue(orderValue);
        adminDepartmentBo.setPage(page);
        adminDepartmentBo.setPageSize(pageSize);
        adminDepartmentBo.setStartPage((page-1)*pageSize);
        CutPageBean<AdminDepartmentPo> cutPageBean = admindepartmentservice.cutPage(adminDepartmentBo);
        return Result.succ(cutPageBean);
    }



//    @PermissionCheck(permissionTypeList  ={PermissionTypeTool.add_perGroup,PermissionTypeTool.edit_perGroup})
    @ApiOperation(value = "更改负责人")
    @PostMapping("editLeader")
    public Result editLeader(
            @RequestBody AdminDepartmentPo adminDepartmentPo,
            HttpServletRequest request
    ) {
        return Result.succ(admindepartmentservice.editLeader(adminDepartmentPo));
//        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
//        adminPermissionGroupPo.setCreteTime(now);
//        adminPermissionGroupPo.setCreateor(TokenUtils.getCurrentUserId(request));
//        return Result.succ(adminPermissionService.addeditPermissionGroup(adminPermissionGroupPo));
    }

    @PermissionCheck(permissionTypeList  ={PermissionTypeTool.sys_mgt})
    @ApiOperation(value = "手动新建/编辑部门")
    @PostMapping("addDepartment")
    @ResponseBody
    public Result addDepartment(
            @RequestBody HashMap<String, String> map,
            HttpServletRequest request
    ) throws IllegalAccessException, NoSuchFieldException {
        String id = map.get("id");
        String name = map.get("name");
//        String higherDepartment = map.get("higherDepartment");
        String higherDepartmentid = map.get("higherDepartmentid");
        if ("".equals(higherDepartmentid)){
            higherDepartmentid = "0";
        }
        if (id.equals(higherDepartmentid)){
            return Result.fail("不能选择当前部门作为父级部门");
        }
        String leaders = map.get("leaders");
        String leadersid = map.get("leadersid");
        String type = map.get("type");

        //当新建的时候，检查id是否存在
        if (type.equals("add")){
            if ("0".equals(id)){
                return Result.fail("部门编号不能为0!");
            }


            boolean exist = admindepartmentservice.isDepartmentcodeExist(id);
            if (exist){
                return Result.fail("部门编号已存在!");
            }
        }

        AdminDepartmentPo departmentPo = new AdminDepartmentPo();
        departmentPo.setDepartmentCode(id);
        departmentPo.setDepartmentName(name);
        departmentPo.setPDepartmentCode(higherDepartmentid);
        departmentPo.setLeaderIDs(leadersid);
        departmentPo.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        departmentPo.setLastUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

        boolean res = admindepartmentservice.addDepartment(departmentPo,type);
        if (res){
            if ("add".equals(type)){
                Boolean insertRes = monitorService.record(request,new MonitorTypeTool().getAddDepartment(),id);
            }

            return Result.succ("成功！");
        }else{
            return Result.fail("失败！");
        }
    }

    @PermissionCheck(permissionTypeList  ={PermissionTypeTool.sys_mgt})
    @ApiOperation(value = "删除部门")
    @PostMapping("deleteDepartment")
    @ResponseBody
    public Result deleteDepartment(
            @RequestBody HashMap<String, String> map,
            HttpServletRequest request
    ) throws NoSuchFieldException, IllegalAccessException {
        String id = map.get("id");

        AdminDepartmentPo departmentPo = new AdminDepartmentPo();
        departmentPo.setDepartmentCode(id);

        boolean isDptEmpty = admindepartmentservice.isDptEmpty(departmentPo);
        if (!isDptEmpty){
            return Result.fail("该部门存在成员,不可删除！");
        }
        boolean res = admindepartmentservice.deleteDepartment(departmentPo);
        if (res){
            Boolean insertRes = monitorService.record(request,new MonitorTypeTool().getDeleteDepartment(),id);
            return Result.succ("删除成功！");
        }else{
            return Result.fail("删除失败！");
        }
    }

    @ApiOperation(value = "下载导入部门的模板")
    @GetMapping("getTemplate")
    public void getTemplate(HttpServletResponse resp, HttpServletRequest request){
        String tpType = request.getParameter("tpType");
        String realPath = "";   //源文件URL
        if("depBatchImp".equals(tpType)){
            realPath = "static/ExcelTemplates/importDepartment.xlsx";
        }
        //- 准备需要下载的文件的文件名
        String fileName = realPath.substring(realPath.lastIndexOf("/") + 1);
        //- 设置浏览器的支持下载
        try {
            resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //- 获取到下载到的文件的输入流
        InputStream in = this.getClass().getClassLoader().getResourceAsStream(realPath);
        //- 创建一个缓冲区用来写入流
        int len = 0;
        byte[] bytes = new byte[1024];
        //- 获取OutputStream对象
        ServletOutputStream outputStream = null;
        try {
            outputStream = resp.getOutputStream();//- 将FileOutputStream对象的流写入到先前创建的buffer缓冲区中,使用OutputStream对象将buffer缓冲区中的数据输出到自己的客户端中
            while ((len = in.read(bytes)) > 0) {
                outputStream.write(bytes, 0, len);
            }
            outputStream.close();
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @ApiOperation(value = "批量导入部门时,接收excel文件的接口")
    @PostMapping("handleBatchImportDpt")
    public Result handleBatchImportDpt(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {
        //步骤一: 获取文件名 AA.xlsx*********************************/
        String fileName = file.getOriginalFilename();
        //步骤二: 为文件AA.xlsx生成随机目录 4D2Gf_AA*****************/
        String dirName = RandomUtils.getRandomString(5) + "_" + fileName.substring(0,fileName.lastIndexOf("."));
        //步骤三: 拼接随机目录+文件名 xxx\4D2Gf_AA
        String dirPath = updDptExcelPath + "\\" + dirName;
        //步骤四: 拼接文件绝对路径 D:\cnki\xxx\4D2Gf_AA\AA.xlsx
        String absPath = dirPath + "\\" + fileName;
        //步骤五: 保存该文件至springboot服务器
        FileUtil.saveFile(file,dirPath,fileName);
        //步骤六: 获取当前系统中所有的部门id
        List<AdminDepartmentPo> allDpts = admindepartmentservice.findAllDept();
        ArrayList<String> allDptIdList = new ArrayList<String>();
        for (AdminDepartmentPo dptPo:allDpts){
            allDptIdList.add(dptPo.getDepartmentCode());
        }

        //步骤七: 验证excel数据合法性
        JSONArray jsonArray = null;
        /*******************步骤七: 检测1 ：excel内容为空检测************************/
        try {
            jsonArray = excelResolve.readExcel(new File(absPath));
            if (jsonArray.size()==0){
                return Result.fail("excel内容为空");
            }
        }catch (Exception e){
            return Result.fail("excel存在空列");
        }

        //特殊步骤: 将excel中的部门编号加入所有部门中,用于判断父部门是否合法
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject lineObject = jsonArray.getJSONObject(i);
            String orgid = lineObject.get("orgid").toString();
            allDptIdList.add(orgid);
        }
        allDptIdList.add("0");

        /*******************步骤七: 检测2 ：表头完整性检测************************/
        ArrayList<String> needHeaders = Lists.newArrayList("orgid", "orgName", "parentId");
        Object[] keysSet = jsonArray.getJSONObject(0).keySet().toArray();
        ArrayList<String> keysList = new ArrayList<String>();
        for ( Object i:keysSet){
            keysList.add(i.toString());
        }
        for (String i :needHeaders){
            if (!keysList.contains(i)){
                return Result.fail("excel缺少必要表头:" + i);
            }
        }
        /*******************步骤七: 检测3 ：单行数据检测************************/
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject lineObject = jsonArray.getJSONObject(i);
            String orgid = lineObject.get("orgid").toString();
            String orgName = lineObject.get("orgName").toString();
            String parentId = lineObject.get("parentId").toString();
            /*******步骤七: 检测3 ：单行数据检测 1:每一行中部分字段是必填************/
            if ("".equals(orgid) || "".equals(orgName)|| "".equals(parentId)){
                return Result.fail(String.format("excel第%d行有空值",i+1));
            }
            /*******步骤七: 检测3 ：单行数据检测 2:部门id不能为0************/
            if ("0".equals(orgid)){
                return Result.fail(String.format("部门编号不能为0,第%s行",i+1));
            }
            /*******步骤七: 检测3 ：单行数据检测 3:部门id必须不存在************/
            //这里注释是因为采用了REC方式,允许部门存在,存在的含义是:修改
            //if (allDptIdList.contains(orgid)){
            //    return Result.fail(String.format("用户编号已存在，不可新建！第%s行",i+1));
            //}


            /**步骤七: 检测3 ：单行数据检测 4:父部门id必须存在(不可能有多个)**/
            if (!allDptIdList.contains(parentId)){
                return Result.fail(String.format("父级部门编号不存在，不可新建！第%s行%s",i+1,parentId));
            }
        }
        //步骤八: 验证通过,将excel数据写入数据库(REC方式)
        boolean res = admindepartmentservice.writeExcelData(jsonArray);

        Boolean insertRes = monitorService.record(request,new MonitorTypeTool().getAddDepartmentBatch(),dirPath);

        return Result.succ(res);
    }
}